#ifndef BASICBODY_H
#define BASICBODY_H
#include <QPointF>

class AABB {
public:
	AABB() {
	}
	AABB(AABB* aabb) {
		this->getMax()->setX(aabb->getMax()->x());
		this->getMax()->setY(aabb->getMax()->y());
		this->getMin()->setX(aabb->getMin()->x());
		this->getMin()->setY(aabb->getMin()->y());
		this->pointSize = aabb->getPointSize();
		this->points = new QPointF[aabb->getPointSize()];
		for (int i = 0;i < aabb->getPointSize();i++) {
			this->points[i] = aabb->getPoints()[i];
		}
	}
	QPointF* getMin() {
		return min;
	}
	QPointF* getMax() {
		return max;
	}

	void setMin(QPointF* point) {
		this->min->setX(point->x());
		this->min->setY(point->y());
	}
	void setMax(QPointF* point) {
		this->max->setX(point->x());
		this->max->setY(point->y());
	}

	void setPoints(QPointF* points) {
		this->points = points;
	}
	QPointF* getPoints() {
		return this->points;
	}

	void setPointSize(int size) {
		this->pointSize = size;
	}

	void setPosition(QPointF* point) {
		this->position->setX(point->x());
		this->position->setY(point->y());
	}

	QPointF* getPosition() {
		return this->position;
	}

	int getPointSize() {
		return this->pointSize;
	}
protected:
	QPointF* min = new QPointF(0.0f, 0.0f);
	QPointF* max = new QPointF(0.0f, 0.0f);
	QPointF* points;
	QPointF* position = new QPointF(0.0f, 0.0f);
	int pointSize;
};

class Body {
public:
	Body();
	~Body();
	virtual QPointF* getPosition();

	virtual void setPosition(QPointF* position);

	virtual QPointF* getVelocity();

	virtual void setVelocity(QPointF* currentVelocity);

	virtual float getAngle();

	virtual float getAngleVelocity() {
		return this->angleVelocity;
	}

	virtual void setAngleVelocity(float angleVelocity) {
		this->angleVelocity = angleVelocity;
	}

	virtual void setAngle(float angle) {
		this->angle = angle;
	}


	virtual void setMass(float mass);

	virtual float getMass();

	virtual void setAABB(AABB* aabb) {
		this->aabb->setMax(aabb->getMax());
		this->aabb->setMin(aabb->getMin());
		this->aabb->setPoints(aabb->getPoints());
		this->aabb->setPointSize(aabb->getPointSize());
	}

	virtual void from(Body* body) {
		QPointF* velocity = body->getVelocity();
		QPointF* position = body->getPosition();
		this->getPosition()->setX(position->x());
		this->getPosition()->setY(position->y());
		this->getVelocity()->setX(velocity->x());
		this->getVelocity()->setY(velocity->y());
	}

	virtual AABB* getAABB() {
		return this->aabb;
	}

	virtual void updateDeltaTimeNoAnyForce(float deltaTime) {
		this->position->setX(this->position->x() + this->velocity->x() * deltaTime);
		this->position->setY(this->position->y() + this->velocity->y() * deltaTime);
	}

	virtual void setId(int id);
	virtual int getId();
private:
	QPointF* position = new QPointF(0.0f, 0.0f);
	QPointF* velocity = new QPointF(0.0f, 0.0f);
	float angle = 0;
	float angleVelocity = 0;
	float mass = 0;
	AABB* aabb = new AABB();
	int id = 0;
};

class RectangleBody :public Body {
public:
	RectangleBody(float w, float h);
	~RectangleBody();
	float getWidth() {
		return width;
	}
	float getHeight() {
		return height;
	}
private:
	float width;
	float height;
};

class TriangleBody :public Body {
public:
	TriangleBody(QPointF a, QPointF b, QPointF c) {
		this->points = new QPointF[3];
		this->points[0] = a;
		this->points[1] = b;
		this->points[2] = c;
	};
	TriangleBody(TriangleBody* triangleBody) {
		this->points = new QPointF[3];
		QPointF* otherPoints = triangleBody->getPoints();
		this->points[0] = otherPoints[0];
		this->points[1] = otherPoints[1];
		this->points[2] = otherPoints[2];
	};
	int getPointSize() {
		return pointSize;
	}
	QPointF* getPoints() {
		return this->points;
	}

private:
	QPointF* points;
	int pointSize = 3;
};



#endif BASICBODY_H